package com.yindian.cos.monitor.aspect;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.yindian.cos.monitor.core.TrackerService;
import com.yindian.cos.monitor.model.Tracker;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.ThreadContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * 监控@LogMonitor，为日志注入参数信息
 *
 * @author zhangchuanhao
 * @date 2018/12/27
 */
@Aspect
@Component
@Log4j2
public class LogMonitorAspect {

    /**
     * 切面
     */
    @Pointcut("@annotation(com.yindian.cos.monitor.annotations.LogMonitor)")
    private void logMonitorCut() {
    }

    /**
     * 进入方法时候的拦截，注入参数信息
     */
    @Before(value = "logMonitorCut()")
    public void doBefore(JoinPoint joinPoint) {
        // 获取当前方法请求参数，放入当前线程
        Object[] args = joinPoint.getArgs();
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();
        Parameter[] parameters = targetMethod.getParameters();
        StringBuffer params = new StringBuffer();
        for (int i = 0; i < parameters.length; i++) {
            try {
                Parameter parameter = parameters[i];
                String type = parameter.getType().getName();
                if (!type.equals(HttpServletRequest.class.getName())
                        && !type.equals(HttpServletResponse.class.getName())
                        && !type.equals(BindingResult.class.getName())) {
                    String parameterName = parameter.getName();
                    String parameterVal = TrackerService.objectMapper.writeValueAsString(args[i]);
                    params.append("[" + parameterName + "=" + parameterVal + "]");
                }
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        Tracker tracker = TrackerService.getTracker();
        tracker.setParams(params.toString());
        TrackerService.setTracker(tracker);
        try {
            ThreadContext.put(TrackerService.TRACKER, TrackerService.objectMapper.writeValueAsString(tracker));
        } catch (JsonProcessingException e) {
            log.error("jackson转换json失败，{}", e);
        }
    }
}

